package com.advertisementsystem.Servie.Impl;

import com.advertisementsystem.Dto.PermissionDTO;
import com.advertisementsystem.Exception.BusinessException;
import com.advertisementsystem.Mapper.PermissionMapper;
import com.advertisementsystem.Servie.PermissionService;
import com.advertisementsystem.entity.Permission;

import com.advertisementsystem.vo.PermissionTreeVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class PermissionServiceImpl implements PermissionService {

    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public List<Permission> getAllPermissions() {
        // 获取所有权限
        List<Permission> allPermissions = permissionMapper.selectList(null);

        // 转换为树形结构（将子权限放到parent的children列表中）
        return buildPermissionHierarchy(allPermissions);
    }

    @Override
    public List<PermissionTreeVO> getPermissionTree() {
        // 获取所有权限
        List<Permission> allPermissions = permissionMapper.selectList(null);

        // 转换为树形结构
        return buildPermissionTree(allPermissions);
    }

    @Override
    @Transactional
    public void addPermission(PermissionDTO permissionDTO) {
        // 检查权限编码是否已存在
        checkPermissionCodeExists(permissionDTO.getCode(), null);

        // 验证父权限是否存在
        if (permissionDTO.getParentId() != null && permissionDTO.getParentId() > 0) {
            Permission parent = permissionMapper.selectById(permissionDTO.getParentId());
            if (parent == null) {
                throw new BusinessException("父权限不存在");
            }
        }

        // 创建权限
        Permission permission = new Permission();
        BeanUtils.copyProperties(permissionDTO, permission);

        // 设置默认值
        LocalDateTime now = LocalDateTime.now();
        permission.setCreatedTime(now);
        permission.setUpdatedTime(now);
        if (permission.getStatus() == null) {
            permission.setStatus(1);
        }
        if (permission.getSortOrder() == null) {
            permission.setSortOrder(0);
        }

        permissionMapper.insert(permission);
    }

    @Override
    @Transactional
    public void updatePermission(Long id, PermissionDTO permissionDTO) {
        // 检查权限是否存在
        Permission existingPermission = permissionMapper.selectById(id);
        if (existingPermission == null) {
            throw new BusinessException("权限不存在");
        }

        // 检查权限编码是否已存在（排除自身）
        checkPermissionCodeExists(permissionDTO.getCode(), id);

        // 验证父权限是否存在，并且不能将自己设为父权限
        if (permissionDTO.getParentId() != null && permissionDTO.getParentId() > 0) {
            if (permissionDTO.getParentId().equals(id)) {
                throw new BusinessException("不能将自己设为父权限");
            }

            Permission parent = permissionMapper.selectById(permissionDTO.getParentId());
            if (parent == null) {
                throw new BusinessException("父权限不存在");
            }

            // 检查是否形成循环依赖
            if (isCircularDependency(id, permissionDTO.getParentId())) {
                throw new BusinessException("不能选择子权限作为父权限，这将导致循环依赖");
            }
        }

        // 更新权限
        Permission permission = new Permission();
        BeanUtils.copyProperties(permissionDTO, permission);
        permission.setId(id);
        permission.setUpdatedTime(LocalDateTime.now());
        permission.setCreatedTime(existingPermission.getCreatedTime());

        permissionMapper.updateById(permission);
    }

    @Override
    @Transactional
    public void deletePermission(Long id) {
        // 检查权限是否存在
        Permission permission = permissionMapper.selectById(id);
        if (permission == null) {
            throw new BusinessException("权限不存在");
        }

        // 检查是否有子权限
        LambdaQueryWrapper<Permission> childQuery = new LambdaQueryWrapper<>();
        childQuery.eq(Permission::getParentId, id);
        Integer childCount = Math.toIntExact(permissionMapper.selectCount(childQuery));
        if (childCount > 0) {
            throw new BusinessException("该权限下有子权限，不能直接删除");
        }

        // 删除权限
        permissionMapper.deleteById(id);
    }

    @Override
    @Transactional
    public void updatePermissionStatus(Long id, Integer status) {
        // 检查权限是否存在
        Permission permission = permissionMapper.selectById(id);
        if (permission == null) {
            throw new BusinessException("权限不存在");
        }

        // 更新状态
        Permission updatePermission = new Permission();
        updatePermission.setId(id);
        updatePermission.setStatus(status);
        updatePermission.setUpdatedTime(LocalDateTime.now());

        permissionMapper.updateById(updatePermission);
    }

    /**
     * 检查权限编码是否已存在
     */
    private void checkPermissionCodeExists(String code, Long excludeId) {
        LambdaQueryWrapper<Permission> query = new LambdaQueryWrapper<>();
        query.eq(Permission::getCode, code);
        if (excludeId != null) {
            query.ne(Permission::getId, excludeId);
        }
        Integer count = Math.toIntExact(permissionMapper.selectCount(query));
        if (count > 0) {
            throw new BusinessException("权限编码已存在");
        }
    }

    /**
     * 检查是否形成循环依赖
     */
    private boolean isCircularDependency(Long sourceId, Long targetParentId) {
        // 获取目标权限的所有子权限
        List<Permission> allPermissions = permissionMapper.selectList(null);
        List<Long> childrenIds = getChildrenIds(allPermissions, sourceId);

        // 如果目标父ID在子权限中，则形成循环
        return childrenIds.contains(targetParentId);
    }

    /**
     * 获取权限的所有子权限ID
     */
    private List<Long> getChildrenIds(List<Permission> permissions, Long parentId) {
        List<Long> result = new ArrayList<>();

        for (Permission permission : permissions) {
            if (parentId.equals(permission.getParentId())) {
                result.add(permission.getId());
                result.addAll(getChildrenIds(permissions, permission.getId()));
            }
        }

        return result;
    }

    /**
     * 构建权限树形结构
     */
    private List<PermissionTreeVO> buildPermissionTree(List<Permission> permissions) {
        List<PermissionTreeVO> result = new ArrayList<>();

        // 先转换所有权限为VO对象
        Map<Long, PermissionTreeVO> permissionMap = permissions.stream()
                .map(this::convertToTreeVO)
                .collect(Collectors.toMap(PermissionTreeVO::getId, p -> p));

        // 构建树形结构
        for (Permission permission : permissions) {
            Long parentId = permission.getParentId();
            // 如果是根节点
            if (parentId == null || parentId == 0) {
                result.add(permissionMap.get(permission.getId()));
            } else {
                // 添加到父节点的children列表
                PermissionTreeVO parentNode = permissionMap.get(parentId);
                if (parentNode != null) {
                    if (parentNode.getChildren() == null) {
                        parentNode.setChildren(new ArrayList<>());
                    }
                    parentNode.getChildren().add(permissionMap.get(permission.getId()));
                }
            }
        }

        // 对结果进行排序
        sortPermissionTree(result);

        return result;
    }

    /**
     * 构建权限层级结构（适用于表格展示）
     */
    private List<Permission> buildPermissionHierarchy(List<Permission> permissions) {
        List<Permission> result = new ArrayList<>();

        // 按parentId分组
        Map<Long, List<Permission>> parentMap = permissions.stream()
                .collect(Collectors.groupingBy(p -> p.getParentId() == null ? 0L : p.getParentId()));

        // 获取顶级节点
        List<Permission> rootNodes = parentMap.getOrDefault(0L, new ArrayList<>());

        // 递归构建树
        for (Permission root : rootNodes) {
            result.add(root);
            buildChildren(root, parentMap);
        }

        // 如果没有按父ID组织的权限，直接返回原列表
        if (result.isEmpty()) {
            return permissions;
        }

        return result;
    }

    /**
     * 递归构建子节点
     */
    private void buildChildren(Permission parent, Map<Long, List<Permission>> parentMap) {
        List<Permission> children = parentMap.getOrDefault(parent.getId(), new ArrayList<>());

        // 如果有子节点，先排序
        if (!children.isEmpty()) {
            children.sort(Comparator.comparing(Permission::getSortOrder, Comparator.nullsLast(Integer::compareTo)));
            parent.setChildren(children);

            // 递归处理子节点
            for (Permission child : children) {
                buildChildren(child, parentMap);
            }
        }
    }

    /**
     * 转换Permission为PermissionTreeVO
     */
    private PermissionTreeVO convertToTreeVO(Permission permission) {
        PermissionTreeVO vo = new PermissionTreeVO();
        BeanUtils.copyProperties(permission, vo);
        return vo;
    }

    /**
     * 对权限树进行排序
     */
    private void sortPermissionTree(List<PermissionTreeVO> permissions) {
        if (permissions == null || permissions.isEmpty()) {
            return;
        }

        // 按sortOrder排序
        permissions.sort(Comparator.comparing(
                PermissionTreeVO::getSortOrder,
                Comparator.nullsLast(Integer::compareTo)
        ));

        // 递归排序子节点
        for (PermissionTreeVO permission : permissions) {
            if (permission.getChildren() != null && !permission.getChildren().isEmpty()) {
                sortPermissionTree(permission.getChildren());
            }
        }
    }
}